package models

import (
	"gintest/database"
	"github.com/jinzhu/gorm"
	"time"
)

type Goods struct{
	Id int `json:"id" gorm:"column:id;primary_key" form:"id"`
	StoreId int `json:"store_id" gorm:"column:store_id" form:"store_id"`
	ClassId int `json:"class_id" gorm:"column:class_id" form:"class_id"`
	CustomId int `json:"custom_id" gorm:"column:custom_id" form:"custom_id"`
	Title string `json:"title" gorm:"column:title" form:"title"`
	//Price float64 `json:"price" gorm:"column:price" form:"price"`
	//Num int `json:"num" gorm:"column:num" form:"num"`
	Status int `json:"status" gorm:"column:status" form:"status"`
	CreateAt time.Time  `json:"create_at" gorm:"column:create_at;type:datetime" time_format:"2006-01-02 15:04:05" form:"create_at"`
	UpdateAt time.Time  `json:"update_at" gorm:"column:update_at;type:datetime" time_format:"2006-01-02 15:04:05" form:"update_at"`
	DeleteAt time.Time  `json:"delete_at" gorm:"column:delete_at;type:datetime" time_format:"2006-01-02 15:04:05" form:"delete_at"`
	//属于关系
	Store Store `json:"store" gorm:"ForeignKeyId:StoreId;AssociationForeignKey:Id"`
	GoodsClass  GoodsClass `json:"goods_class" gorm:"ForeignKey:ClassId;AssociationForeignKey:Id"`
	StoreCustomClass  StoreCustomClass `json:"store_custom_class" gorm:"ForeignKey:CustomId;AssociationForeignKey:Id"`
	//包含关系
	GoodsContent  GoodsContent `json:"goods_content" gorm:"ForeignKey:GoodsId;AssociationForeignKey:Id"`
	GoodsSpec  []GoodsSpec `json:"goods_spec" gorm:"ForeignKey:GoodsId;AssociationForeignKey:Id"`
	GoodsAttr []GoodsAttr `json:"goods_attr" gorm:"ForeignKey:GoodsId;AssociationForeignKey:Id"`
}
func (Goods) TableName() string {
	return "goods"
}

func GetGoodsList(page uint64,pagesize uint64,keyword string,store_id,status uint64)(data []Goods,total uint64){
	var offset=(page-1)*pagesize
	db:=database.SqlDB.Model(Goods{})

	if len(keyword)!=0{
		db=db.Where("concat(id,title) like ?","%"+keyword+"%")
	}
	if store_id!=0 {
		db=db.Where("store_id=?",store_id)
	}
	if status!=0 {
		db=db.Where("status=?",status)
	}
	db=db.Where("delete_at = 0 or delete_at is null")

	db.Preload("Store").Preload("GoodsClass").Preload("StoreCustomClass").Preload("GoodsSpec",func(db *gorm.DB) *gorm.DB {
		return db.Order("def asc,price asc")
	}).Offset(offset).Limit(pagesize).Order("id desc").Find(&data)

	db.Model(Goods{}).Count(&total)
	return data,total
}

func AddGoods(data *Goods) error{
	if data.UpdateAt.IsZero(){
		data.UpdateAt=time.Now()
	}
	if data.CreateAt.IsZero(){
		data.CreateAt=time.Now()
	}
	return database.SqlDB.Model(Goods{}).Omit("Store","GoodsClass","StoreCustomClass","GoodsAttr").Create(data).Error
}
func DelGoodsByIds(ids []int) error{
	//return database.SqlDB.Model(User{}).Where("id in (?)",ids).Delete(User{}).Error
	return database.SqlDB.Model(Goods{}).Where("id in (?) and (delete_at = 0 or delete_at is null)",ids).Update("delete_at",time.Now().Local().String()).Error
}
func GetGoodsById(id int) (data Goods){
	database.SqlDB.Model(Goods{}).Preload("Store").Preload("GoodsClass").Preload("StoreCustomClass").Preload("GoodsContent").Preload("GoodsSpec",func(db *gorm.DB) *gorm.DB {
		return db.Order("def asc,price asc")
	}).Preload("GoodsSpec.GoodsImage").Preload("GoodsAttr",func(db *gorm.DB) *gorm.DB {
		return db.Order("attribute_id asc")
	}).Preload("GoodsAttr.GoodsAttribute").Preload("GoodsAttr.GoodsAttribute.GoodsAttributeValue").Where("id=?",id).First(&data);
	return data
}
func EditGoodsById(data *Goods) error{
	if data.UpdateAt.IsZero(){
		data.UpdateAt=time.Now()
	}
	tx:=database.SqlDB.Begin()
	spec_ids:=[]int{}
	for _, v := range data.GoodsSpec {
		spec_ids=append(spec_ids,v.Id)
	}
	if len(spec_ids)>0{
		err:=tx.Where("spec_id in (?)",spec_ids).Delete(&GoodsImage{}).Error
		if err!=nil{
			tx.Rollback()
			return err
		}
	}
	err:=tx.Where("goods_id=?",data.Id).Delete(&GoodsContent{}).Error
	if err!=nil{
		tx.Rollback()
		return err
	}
	err=tx.Model(Goods{}).Omit("StoreId","ClassId","Store","GoodsClass","StoreCustomClass","GoodsAttr").Save(data).Error
	if err!=nil{
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}
func EditGoodsStatusById(id,status uint64) error{
	return database.SqlDB.Model(Goods{}).Where("id=?",id).Update("status",status).Error
}

func SaveGoodsAttr(data []GoodsAttr,flag bool) error{
	tx:=database.SqlDB.Begin()
	goods_ids:=make(map[int]int,10)
	for i:=0;i<len(data);i++{
		if flag==false{//新增
			if data[i].AttributeId>0{
				if _, ok := goods_ids[data[i].GoodsId]; !ok{
					err:=tx.Where("goods_id=?",data[i].GoodsId).Delete(&GoodsAttr{}).Error
					if err!=nil{
						tx.Rollback()
						return err
					}
					goods_ids[data[i].GoodsId]=data[i].AttributeId
				}	
			}
		}else{//编辑
			if _, ok := goods_ids[data[i].GoodsId]; !ok{
				err:=tx.Where("goods_id=?",data[i].GoodsId).Delete(&GoodsAttr{}).Error
				if err!=nil{
					tx.Rollback()
					return err
				}
				goods_ids[data[i].GoodsId]=data[i].AttributeId
			}
		}
		
		err:=tx.Model(GoodsAttr{}).Save(&data[i]).Error
		if err!=nil{
			tx.Rollback()
			return err
		}
	}
	tx.Commit()
	return nil
}
func DelGoodsAttr(id int) error{
	tx:=database.SqlDB.Begin()
	err:=tx.Where("goods_id=?",id).Delete(GoodsAttr{}).Error
	if err!=nil{
		tx.Rollback()
		return err
	}
	err=tx.Where("goods_id=? and def!=1",id).Delete(GoodsSpec{}).Error
	if err!=nil{
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}
func SaveGoodsSpec(data []GoodsSpec) error{
	tx:=database.SqlDB.Begin()
	var ids []int
	var goods_ids []int
	for i:=0;i<len(data);i++{
		if data[i].Id>0{
			ids=append(ids,data[i].Id)
		}
		goods_ids=append(goods_ids,data[i].GoodsId)
	}
	
	if len(ids)>0{
		err:=tx.Where("id not in (?) and goods_id in (?) and def!=1",ids,goods_ids).Delete(GoodsSpec{}).Error
		if err!=nil{
			tx.Rollback()
			return err
		}
	}else if len(data)>0{
		err:=tx.Where("goods_id in (?) and def!=1",goods_ids).Delete(GoodsSpec{}).Error
		if err!=nil{
			tx.Rollback()
			return err
		}
	}

	for i:=0;i<len(data);i++{
		err:=tx.Model(GoodsSpec{}).Save(&data[i]).Error
		if err!=nil{
			tx.Rollback()
			return err
		}
	}
	tx.Commit()
	return nil
}
